package edu.moravian.entity;

import edu.moravian.math.Point2D;
import edu.moravian.math.Vector2D;

/**
 *
 * @author Elliot
 *
 * This is the base class for all agents. All agents should have a location,
 * heading, speed, width, height and mass. For stationary agents speed and heading
 * should be zero
 */
public abstract class AbstractEntity
{

    /**
     * The location of the agent
     */
    protected Point2D location;
    /**
     * The heading of the agent. This should be a normalized vector.
     * An agents velocity is defined by its heading and speed. Set to zero
     * if you want a stationary agent
     */
    protected Vector2D heading;
    /**
     * The speed of the agent. This is part of velocity. Set to zero
     * if you want a stationary agent
     */
    protected double speed;
    /**
     * The width of the agent
     */
    protected double width;
    /**
     * The height of the agent;
     */
    protected double height;
    /**
     * The mass of the agent
     */
    protected double mass;

    
    /**
     * Update the location
     *
     * @param loc the location to update to
     */
    public void setLocation(Point2D loc)
    {
        location.set(loc);
    }



    /**
     * Get the current location
     *
     * @return the location
     */
    public Point2D getLocation()
    {
        return location;
    }



    /**
     * Update the heading to match the heading of the vector passed in
     *
     * @param vec the vector that has the heading you want your heading to mimic
     * (actual heading is a normal vector so the vector passed in will be
     * normalized
     * just in case)
     */
    public void setHeading(Vector2D vec)
    {

        heading.set(vec);
        heading.normalize();
    }




    /**
     * Get the current normalized heading
     *
     * @return the heading
     */
    public Vector2D getHeading()
    {
        return heading;
    }




    /**
     * Update the current speed
     *
     * @param speed
     */
    public void setSpeed(double speed)
    {
        this.speed = speed;
    }




    /**
     * Get the current speed
     *
     * @return the speed
     */
    public double getSpeed()
    {
        return speed;
    }




    /**
     * Set the current width
     *
     * @param width
     */
    public void setWidth(double width)
    {
        this.width = width;
    }




    /**
     * Get the current
     *
     * @return the width
     */
    public double getWidth()
    {
        return width;
    }




    /**
     * Set the current height
     *
     * @param height
     */
    public void setHeight(double height)
    {
        this.height = height;
    }




    /**
     * Get the current height
     *
     * @return the Height
     */
    public double getHeight()
    {
        return height;
    }

    /**
     * Get the current mass 
     * 
     * @return the mass
     */
    public double getMass()
    {
        return mass;
    }
    
    
    
    /**
     * set the current mass
     * 
     * @param mass 
     */
    public void setMass(double mass)
    {
        this.mass = mass;
    }



    /**
     * Size is defined as larger of width and height
     * Thus radius is going to be half height.
     *
     * @return the max of the width and height
     */
    public double getRadius()
    {
        return (Math.max(height, width)/2.0);
    }

    
    /**
     * The velocity of an agent is the agents
     * speed and direction
     * 
     * @return the velocity (speed * direction)
     */
    public Vector2D getVelocity()
    {
        return heading.times(speed);
    }



    /**
     * For all agents to implement their own update method
     *
     * @param delta
     */
    public abstract void update(double delta);




}



